﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using BGM.Domain.DTO;
using System.Globalization;
namespace BGM.Core.DAL
{
    public class PerisitenceManager
    {
        private const string FILE_NAME = "BGM_Data.xml";
        private const string DIRECTORY_NAME = "Data";
        string file;
        public PerisitenceManager()
        {

            string directory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, DIRECTORY_NAME);
            if (!Directory.Exists(directory))
                Directory.CreateDirectory(DIRECTORY_NAME);
            file = Path.Combine(directory, FILE_NAME);
            if (!File.Exists(file))
                CreateDataFile();
        }
        private void CreateDataFile()
        {
            XElement root = new XElement("BloodGlucoseManager",
                                       new XElement("Paitent",
                       new XAttribute("Name", "Test Person 1"),
                       new XAttribute("SSN", "19900101"),
                      new XElement("Settings",
                          new XElement("Time",
                              new XElement("Morning", "7:00"),
                              new XElement("MidtDay", "12:00"),
                              new XElement("Dinner", "19:00"),
                              new XElement("Night", "23:00")),
                          new XElement("LevelIndicator",
                              new XElement("Low", "4"),
                              new XElement("High", "9"))),
                      new XElement("Readings",
                            new XElement("Reading",
                                new XAttribute("Date", DateTime.Now.ToString()),
                                new XElement("Level",
                                    new XAttribute("Type", "mg/dl"),
                                    "6")))),
                                    new XElement("Paitent",
                       new XAttribute("Name", "Test Person 2"),
                       new XAttribute("SSN", "19900102"),
                      new XElement("Settings",
                          new XElement("Time",
                              new XElement("Morning", "7:00"),
                              new XElement("MidtDay", "12:00"),
                              new XElement("Dinner", "19:00"),
                              new XElement("Night", "23:00")),
                          new XElement("LevelIndicator",
                              new XElement("Low", "4"),
                              new XElement("High", "9"))),
                      new XElement("Readings",
                            new XElement("Reading",
                                new XAttribute("Date", DateTime.Now.ToString()),
                                new XElement("Level",
                                    new XAttribute("Type", "mg/dl"),
                                    "6")))));

            root.Save(file);
        }
        public List<Patient> GetPatients()
        {
            var result = from e in XElement.Load(file).Elements("Paitent")
                         select new Patient
                         {
                             Ssn = (string)e.Attribute("SSN"),
                             Name = (string)e.Attribute("Name"),
                             Times =
                             {
                                 Morning = DateTime.ParseExact((string)e.Element("Settings").Element("Time").Element("Morning"), "H:mm", new System.Globalization.NumberFormatInfo()),
                                 MidtDay = DateTime.ParseExact((string)e.Element("Settings").Element("Time").Element("MidtDay"), "H:mm", new System.Globalization.NumberFormatInfo()),
                                 Dinner = DateTime.ParseExact((string)e.Element("Settings").Element("Time").Element("Dinner"), "H:mm", new System.Globalization.NumberFormatInfo()),
                                 Night = DateTime.ParseExact((string)e.Element("Settings").Element("Time").Element("Night"), "H:mm", new System.Globalization.NumberFormatInfo()),
                             },
                             LevelIndicator =
                             {
                                 Low = (int)e.Element("Settings").Element("LevelIndicator").Element("Low"),
                                 High = (int)e.Element("Settings").Element("LevelIndicator").Element("High")
                             }
                         };
            //List<KeyValuePair<string, string>> paitents = new List<KeyValuePair<string, string>>();
            //foreach (var item in result)
            //{
            //    paitents.Add(new KeyValuePair<string, string>(item.Ssn, item.Name));
            //}
            //return paitents;
            return result.ToList();
        }
        private bool isWorkingDay(DateTime date)
        {
            if (date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday)
                return false;
            else
                return true;
        }
        public List<Reading> GetReadings(string SSN, DateTime start, DateTime end, bool onlyWorkingDays)
        {

            start = new DateTime(start.Year, start.Month, start.Day);
            end = new DateTime(end.Year, end.Month, end.Day);
            var list = from b in XElement.Load(file).Elements("Paitent")
                       where ((string)b.Attribute("SSN")).Equals(SSN)
                       from c in b.Element("Readings").Elements("Reading")
                       where (DateTime.Parse(DateTime.Parse((string)c.Attribute("Date")).ToShortDateString()).CompareTo(start) >= 0
                       &&
                       DateTime.Parse(DateTime.Parse((string)c.Attribute("Date")).ToShortDateString()).CompareTo(end) <= 0)
                       &&
                       ((isWorkingDay(DateTime.Parse((string)c.Attribute("Date"))) && onlyWorkingDays) || !onlyWorkingDays)
                       select new Reading
                      {
                          TimeStamp = DateTime.Parse((string)c.Attribute("Date")),
                          Value = double.Parse((string)c.Element("Level"), ci.NumberFormat)//,
                          //Type = Reading.ReadingType.BloodGlucoseReading

                      };

            /*
            foreach (var item in list)
            {
                Trace.WriteLine(item.Value);
            }
             */
            var listSorted = list.ToList();
            listSorted.Sort();
            return listSorted;
        }
        CultureInfo ci = new CultureInfo("EN-US");
        public void SaveReadings(string SSN, List<Reading> readings)
        {
            if (readings != null && readings.Count > 0)
            {
                readings.Sort();
                DateTime start, end;
                if (readings[0].TimeStamp > readings[readings.Count - 1].TimeStamp)
                {
                    start = readings[readings.Count - 1].TimeStamp;
                    end = readings[0].TimeStamp;
                }
                else
                {
                    start = readings[0].TimeStamp;
                    end = readings[readings.Count - 1].TimeStamp;
                }

                XElement doc = XElement.Load(file);

                //find patient
                var patients = (from b in doc.Elements("Paitent")
                                where ((string)b.Attribute("SSN")).Equals(SSN)
                                select b.Element("Readings"));
                List<Reading> list = GetReadings(SSN, start, end, false);
                if (list == null)
                    list = new List<Reading>();
                var r = from c in readings
                        where !list.Contains(c)
                        select new XElement("Reading",
                                    new XAttribute("Date", c.TimeStamp.ToString()),
                                    new XElement("Level",
                                        new XAttribute("Type", "mg/dl"),
                                        c.Value.ToString(ci.NumberFormat)));

                foreach (var item in patients)
                {
                    item.Add(r);
                }
                doc.Save(file);
            }

        }

        public void CreatePatient(string name, string ssn, DateTime morning, DateTime midtDay, DateTime dinner, DateTime neight, int low, int high)
        {
            XElement doc = XElement.Load(file);

            //find patient
            var patients = (from b in doc.Elements("Paitent")
                            where ((string)b.Attribute("SSN")).Equals(ssn)
                            select b);

            doc.AddFirst(

             new XElement("Paitent",
                          new XAttribute("SSN",ssn),
                          new XAttribute("Name",name),
                          new XElement("Settings",
                              new XElement("Time",
                                  new XElement("Morning",morning.ToShortTimeString()),
                                  new XElement("MidtDay",midtDay.ToShortTimeString()),
                                  new XElement("Dinner",dinner.ToShortTimeString()),
                                  new XElement("Night",neight.ToShortTimeString())),
                              new XElement("LevelIndicator",
                                new XElement("Low",low),
                                new XElement("High", high))),
                              new XElement("Readings")));


            doc.Save(file);
        }
    }
}
